/**
 * 颜色模块 - 提供颜色转换和处理功能
 */

/**
 * 十六进制颜色转RGB
 * @param {string} hex 十六进制颜色
 * @returns {Object|null} RGB对象
 */
export function hexToRgb(hex) {
  if (typeof hex !== 'string') return null;

  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

/**
 * RGB转十六进制颜色
 * @param {number} r 红色值 (0-255)
 * @param {number} g 绿色值 (0-255)
 * @param {number} b 蓝色值 (0-255)
 * @returns {string} 十六进制颜色
 */
export function rgbToHex(r, g, b) {
  if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number') {
    return '#000000';
  }

  function toHex(n) {
    const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
    return hex.length === 1 ? '0' + hex : hex;
  }

  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

/**
 * RGB转HSL
 * @param {number} r 红色值 (0-255)
 * @param {number} g 绿色值 (0-255)
 * @param {number} b 蓝色值 (0-255)
 * @returns {Object} HSL对象
 */
export function rgbToHsl(r, g, b) {
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h, s;
  const l = (max + min) / 2;

  if (max === min) {
    h = s = 0; // achromatic
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);

    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }

  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100)
  };
}

/**
 * HSL转RGB
 * @param {number} h 色调 (0-360)
 * @param {number} s 饱和度 (0-100)
 * @param {number} l 亮度 (0-100)
 * @returns {Object} RGB对象
 */
export function hslToRgb(h, s, l) {
  h /= 360;
  s /= 100;
  l /= 100;

  function hue2rgb(p, q, t) {
    if (t < 0) t += 1;
    if (t > 1) t -= 1;
    if (t < 1/6) return p + (q - p) * 6 * t;
    if (t < 1/2) return q;
    if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
    return p;
  }

  let r, g, b;

  if (s === 0) {
    r = g = b = l; // achromatic
  } else {
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    r = hue2rgb(p, q, h + 1/3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1/3);
  }

  return {
    r: Math.round(r * 255),
    g: Math.round(g * 255),
    b: Math.round(b * 255)
  };
}

/**
 * 生成随机颜色
 * @param {string} format 格式 ('hex' | 'rgb' | 'hsl')
 * @returns {string|Object} 随机颜色
 */
export function randomColor(format = 'hex') {
  const r = Math.floor(Math.random() * 256);
  const g = Math.floor(Math.random() * 256);
  const b = Math.floor(Math.random() * 256);

  switch (format) {
    case 'rgb':
      return { r, g, b };
    case 'hsl':
      return rgbToHsl(r, g, b);
    case 'hex':
    default:
      return rgbToHex(r, g, b);
  }
}

/**
 * 调整颜色亮度
 * @param {string} hex 十六进制颜色
 * @param {number} percent 调整百分比 (-100 到 100)
 * @returns {string} 调整后的颜色
 */
export function adjustBrightness(hex, percent) {
  const rgb = hexToRgb(hex);
  if (!rgb) return hex;

  function adjust(value) {
    const adjusted = value + (value * percent / 100);
    return Math.max(0, Math.min(255, adjusted));
  }

  return rgbToHex(adjust(rgb.r), adjust(rgb.g), adjust(rgb.b));
}

/**
 * 获取颜色的对比色
 * @param {string} hex 十六进制颜色
 * @returns {string} 对比色
 */
export function getContrastColor(hex) {
  const rgb = hexToRgb(hex);
  if (!rgb) return '#ffffff';

  // 使用YIQ公式计算亮度
  const yiq = ((rgb.r * 299) + (rgb.g * 587) + (rgb.b * 114)) / 1000;
  return yiq >= 128 ? '#000000' : '#ffffff';
}

/**
 * 判断颜色是否为浅色
 * @param {string} hex 十六进制颜色
 * @returns {boolean} 是否为浅色
 */
export function isLight(hex) {
  return getContrastColor(hex) === '#000000';
}

/**
 * 判断颜色是否为深色
 * @param {string} hex 十六进制颜色
 * @returns {boolean} 是否为深色
 */
export function isDark(hex) {
  return getContrastColor(hex) === '#ffffff';
}

/**
 * 颜色混合
 * @param {string} hex1 颜色1
 * @param {string} hex2 颜色2
 * @param {number} ratio 混合比例 (0-1)
 * @returns {string} 混合后的颜色
 */
export function mixColors(hex1, hex2, ratio = 0.5) {
  const rgb1 = hexToRgb(hex1);
  const rgb2 = hexToRgb(hex2);

  if (!rgb1 || !rgb2) return hex1;

  const r = Math.round(rgb1.r + (rgb2.r - rgb1.r) * ratio);
  const g = Math.round(rgb1.g + (rgb2.g - rgb1.g) * ratio);
  const b = Math.round(rgb1.b + (rgb2.b - rgb1.b) * ratio);

  return rgbToHex(r, g, b);
}

/**
 * 验证颜色格式
 * @param {string} color 颜色字符串
 * @returns {Object} 验证结果
 */
export function validateColor(color) {
  if (typeof color !== 'string') {
    return { valid: false, format: null };
  }

  // 十六进制
  if (/^#[0-9A-Fa-f]{6}$/.test(color)) {
    return { valid: true, format: 'hex' };
  }

  // RGB
  if (/^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/.test(color)) {
    return { valid: true, format: 'rgb' };
  }

  // RGBA
  if (/^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*(0|1|0\.\d+)\s*\)$/.test(color)) {
    return { valid: true, format: 'rgba' };
  }

  // HSL
  if (/^hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)$/.test(color)) {
    return { valid: true, format: 'hsl' };
  }

  return { valid: false, format: null };
}

/**
 * 常用颜色名称映射
 */
const COLOR_NAMES = {
  red: '#ff0000',
  green: '#008000',
  blue: '#0000ff',
  yellow: '#ffff00',
  orange: '#ffa500',
  purple: '#800080',
  pink: '#ffc0cb',
  brown: '#a52a2a',
  gray: '#808080',
  grey: '#808080',
  black: '#000000',
  white: '#ffffff',
  cyan: '#00ffff',
  magenta: '#ff00ff',
  lime: '#00ff00',
  navy: '#000080',
  maroon: '#800000',
  olive: '#808000',
  teal: '#008080',
  silver: '#c0c0c0'
};

/**
 * 颜色名称转十六进制
 * @param {string} name 颜色名称
 * @returns {string|null} 十六进制颜色
 */
export function nameToHex(name) {
  if (typeof name !== 'string') return null;
  return COLOR_NAMES[name.toLowerCase()] || null;
}

/**
 * 获取颜色调色板
 * @param {string} baseColor 基础颜色
 * @param {number} count 颜色数量
 * @returns {string[]} 颜色调色板
 */
export function getColorPalette(baseColor, count = 5) {
  const rgb = hexToRgb(baseColor);
  if (!rgb) return [];

  const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
  const palette = [];

  for (let i = 0; i < count; i++) {
    const lightness = Math.round(20 + (60 / count) * i);
    const color = hslToRgb(hsl.h, hsl.s, lightness);
    palette.push(rgbToHex(color.r, color.g, color.b));
  }

  return palette;
}
